package com.xiaoyu.stack;

import java.util.LinkedList;
import java.util.Queue;

/**
 * @program: DS_and_A
 * @description: 用队列实现栈
 *
 * 请你仅使用两个队列实现一个后入先出（LIFO）的栈，并支持普通队列的全部四种操作（push、top、pop 和 empty）。
 *
 * 实现 MyStack 类：
 *
 * void push(int x) 将元素 x 压入栈顶。
 * int pop() 移除并返回栈顶元素。
 * int top() 返回栈顶元素。
 * boolean empty() 如果栈是空的，返回 true ；否则，返回 false 。
 *
 * 注意：
 *
 * 你只能使用队列的基本操作 —— 也就是push to back、peek/pop from front、size 和is empty这些操作。
 * 你所使用的语言也许不支持队列。你可以使用 list （列表）或者 deque（双端队列）来模拟一个队列, 只要是标准的队列操作即可。
 *
 * @author: YuWenYi
 * @create: 2021-05-07 09:48
 **/

//使用两个队列实现栈--->简单解释:
//元素入队列2,然后把队列1中的所有元素入队列2,此时队列2即完成了栈的功能,即后入的元素在头部,然后把队列2的所有值都给队列1即可
/*public class MyStack {
    Queue<Integer> queue1;
    Queue<Integer> queue2;

    *//** Initialize your data structure here. *//*
    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }

    *//** Push element x onto stack. *//*
    public void push(int x) {
        //当最新的元素放入到队列头
        queue2.offer(x);
        //队列2接收队列1的所有元素,将它们放到最新的元素后面
        while (!queue1.isEmpty()){
            queue2.offer(queue1.poll());
        }
        //然后将获取了所有元素的队列2,重新给队列1,这样新添加的元素就在队列头了!
        while (!queue2.isEmpty()){
            queue1.offer(queue2.poll());
        }
    }

    *//** Removes the element on top of the stack and returns that element. *//*
    public int pop() {
        if (!queue1.isEmpty()){
            return queue1.poll();
        }
        throw new RuntimeException();
    }

    *//** Get the top element. *//*
    public int top() {
        if (!queue1.isEmpty()){
            return queue1.peek();
        }
        throw new RuntimeException();
    }

    *//** Returns whether the stack is empty. *//*
    public boolean empty() {
        return queue1.isEmpty();
    }

    public static void main(String[] args) {
        MyStack myStack = new MyStack();
        myStack.push(1);
        myStack.push(2);
        System.out.println(myStack.top());
        System.out.println(myStack.pop());
        System.out.println(myStack.empty());
    }
}*/

//解法二:用一个队列实现栈
//例如:队列中已经有:1,2,3,4,此时入10,那么先n=4 然后入队列:1,2,3,4,10,然后把10前面的所有值出队后重新入队列:10,1,2,3,4
public class MyStack{
    Queue<Integer> queue1;

    /** Initialize your data structure here. */
    public MyStack() {
        queue1 = new LinkedList<>();
    }

    public void push(int x) {
        //记录新的值入队列之前,整个队列的元素个数
        int n = queue1.size();

        //然后把这个值入队列
        queue1.offer(x);

        //然后把该值的前面的所有值,重新入队列,即完成栈操作
        for (int i = 0; i < n; i++) {
            queue1.offer(queue1.poll());
        }
    }

    public int pop() {
        if (!queue1.isEmpty()){
            return queue1.poll();
        }
        throw new RuntimeException();
    }

    public int top() {
        if (!queue1.isEmpty()){
            return queue1.peek();
        }
        throw new RuntimeException();
    }

    public boolean empty() {
        return queue1.isEmpty();
    }

    public static void main(String[] args) {
        MyStack myStack = new MyStack();
        myStack.push(1);
        myStack.push(2);
        System.out.println(myStack.top());
        System.out.println(myStack.pop());
        System.out.println(myStack.empty());
    }
}